import { service } from './service'

import { config } from './config'
import { messageC } from '../util/common'
import Axios from 'axios'

const { default_headers } = config

const CancelToken = Axios.CancelToken;
const source = CancelToken.source();

const request = (option: any) => {
  const { url, method, params, data, headersType, responseType, ...config } = option
  return service({
    url: url,
    method,
    params,
    data,
    ...config,
    responseType: responseType,
    cancelToken: source.token ,
    headers: {
      'Content-Type': headersType || default_headers
    },
  })
}

// 导出、文件流下载
const fileDownload = (res: any) => {
  const str = res.headers['content-disposition']
  if (!res || !str) {
    messageC(res.message || '下载失败！')
    return
  }
  if (res && res.status === 200 && res.data) {
      const { data, headers } = res
      let fileName
      if (headers['content-disposition']) {
        fileName = headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1')
      } else {
        fileName = data.fileName
      }

      fileName = decodeURIComponent(fileName)
      let fileNames = fileName.split(";")
      let firstFileNameIndex = fileNames.findIndex(i => i.indexOf('filename=') != -1)
      if(firstFileNameIndex != -1) {
        fileName = fileNames[firstFileNameIndex].replace('filename=', "").replace(/\s/g, '')
        fileName = fileName.replace(/"/g, '')
      }
      fileName = fileName.replace('attachment;fileName=', '')
      // 此处当返回json文件时需要先对data进行JSON.stringify处理，其他类型文件不用做处理
      const blob = new Blob([data], { type: headers['content-type'] })

      let objectUrl = URL.createObjectURL(blob);
      var downloadElement = document.createElement('a');
      downloadElement.href = objectUrl;
      downloadElement.download = fileName;
      downloadElement.click();
  } else {
    messageC(res.message || '下载失败！')
  }
}

export default {
  get: async <T = any>(option: any) => {
    const res = await request({ method: 'GET', ...option })
    let tData = res.data;
    if(tData && typeof tData != 'string') {
      if(option['params']) {
        tData.originData = option['params']
      } else {
        let urls = (option.url || '').split('?');
        if(urls.length > 1) {
          tData.originData = urls[1].split('&').map((i : any) => {
            let param: any[] = (i || '').split('=')
            let obj: any = {};
            obj[param[0]] = param.length > 1 ? param[1] : ''
            return obj
          })
        }
      }
    }
    return tData as unknown as T
  },
  post: async <T = any>(option: any) => {
    const res = await request({ method: 'POST', ...option })
    let tData = res.data;
    if(tData) {
      tData.originData = option.data
    }
    return tData as unknown as T
  },
  postOriginal: async (option: any) => {
    const res = await request({ method: 'POST', ...option })
    return res
  },
  delete: async <T = any>(option: any) => {
    const res = await request({ method: 'DELETE', ...option })
    return res.data as unknown as T
  },
  put: async <T = any>(option: any) => {
    const res = await request({ method: 'PUT', ...option })
    return res.data as unknown as T
  },
  download: async <T = any>(option: any) => {
    const res = await request({ method: 'GET', responseType: 'blob', ...option })
    return res as unknown as Promise<T>
  },
  download1: async <T = any>(option: any) => {
    const res = await request({ method: 'POST', responseType: 'blob', ...option })
    fileDownload(res)
    return res as unknown as Promise<T>
  },
  upload: async <T = any>(option: any) => {
    option.headersType = 'multipart/form-data'
    const res = await request({ method: 'POST', ...option })
    // return request({ method: 'POST', ...option})
    return res as unknown as Promise<T>
  }
}
